package com.chushouya.order.dao.repository;


import com.general.framework.core.lang.*;
import com.general.framework.core.schema.PageResult;
import com.general.framework.data.mybatis.BaseRepository;
import com.chushouya.manager.constants.PartnerTypeEnum;
import com.chushouya.order.constants.LogisticsStatusEnum;
import com.chushouya.order.constants.OrderPayStatusEnum;
import com.chushouya.order.constants.OrderStatusEnum;
import com.chushouya.order.dao.entity.OrderEntity;
import com.chushouya.order.dao.mapper.OrderEntityMapper;
import com.chushouya.order.dto.admin.order.OrderQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 订单Repository
 */
@Repository
@Slf4j
public class OrderRepository extends BaseRepository<OrderEntityMapper, OrderEntity, Long> {

    public OrderEntity selectOne(OrderQuery query) {
        return this.selectFirstOneByExample(this.buildExample(query));
    }

    public PageResult<OrderEntity> selectPageResult(OrderQuery query) {
        final Example example = this.buildExample(query);
        example.orderBy("orderId").desc();
        return selectPage(query.getPageRequest(), example);
    }

    public PageResult<OrderEntity> selectStockPageResult(OrderQuery query) {
        final Example example = this.buildExample(query);
        example.orderBy("completeTime").desc();
        return selectPage(query.getPageRequest(), example);
    }

    public boolean existsOrderNo(String orderNo) {
        final Example example = this.buildExample();
        example.and().andEqualTo("orderNo", orderNo);
        return this.selectCountByExample(example) > 0;
    }

    private Example buildExample(OrderQuery query) {
        Example example = this.buildExample();
        if (Strings.isNotEmpty(query.getOrderNo())) {
            example.and().andEqualTo("orderNo", query.getOrderNo());
        }
        if (Objects.nonNull(query.getOrderId())) {
            example.and().andEqualTo("orderId", query.getOrderId());
        }
        if (Lists.isNotEmpty(query.getOrderList())) {
            example.and().andIn("orderId", query.getOrderList());
        }
        if (Strings.isNotEmpty(query.getKeyword())) {
            final String keyword = query.getKeyword().trim();
            example.and().andLike("orderNo", Strings.format("%{}%", keyword))
                    .orLike("userName", Strings.format("%{}%", keyword))
                    .orLike("partnerOrderNo", Strings.format("%{}%", keyword))
                    .orLike("userPhone", Strings.format("%{}%", keyword))
                    .orLike("orderId", Strings.format("%{}%", keyword));
        }
        if (Strings.isNotEmpty(query.getAscriptionKeyword())) {
            final String keyword = query.getAscriptionKeyword().trim();
            example.and().orEqualTo("orderNo", keyword)
                    .orEqualTo("partnerOrderNo", keyword)
                    .orEqualTo("userPhone", keyword);
        }
        if(Integers.notNullAndZero(query.getBizType())){
            example.and().andEqualTo("bizType", query.getBizType());
        }
        if (Integers.notNullAndZero(query.getOrderType())) {
            example.and().andEqualTo("orderType", query.getOrderType());
        }
        if (Longs.notNullAndZero(query.getKefuId())) {
            example.and().andEqualTo("kefuId", query.getKefuId());
        }
        if (Strings.isNotEmpty(query.getKefuName())) {
            example.and().andLike("kefuName", Strings.format("%{}%", query.getKefuName()));
        }
        if (Objects.nonNull(query.getOrderStatus())) {
            example.and().andEqualTo("orderStatus", query.getOrderStatus());
        }
        if(Lists.isNotEmpty(query.getOrderSourceList())){
            example.and().andIn("orderSource", query.getOrderSourceList());
        }
        if (Lists.isNotEmpty(query.getOrderStatusList())) {
            example.and().andIn("orderStatus", query.getOrderStatusList());
        }
        if (Lists.isNotEmpty(query.getIgnoreOrderStatus())) {
            example.and().andNotIn("orderStatus", query.getIgnoreOrderStatus());
        }
        if (Longs.notNullAndZero(query.getUserId())) {
            example.and().andEqualTo("userId", query.getUserId());
        }
        if (Longs.notNullAndZero(query.getClerkId())) {
            example.and().andEqualTo("clerkId", query.getClerkId());
        }
        if (Strings.isNotEmpty(query.getClerkName())) {
            example.and().andLike("clerkName", Strings.format("%{}%", query.getClerkName()));
        }
        if (Strings.isNotEmpty(query.getPartnerOrderNo())) {
            example.and().andEqualTo("partnerOrderNo", query.getPartnerOrderNo());
        }
        if (Objects.nonNull(query.getAppointStartTime()) && Objects.nonNull(query.getAppointEndTime())) {
            example.and().andGreaterThanOrEqualTo("appointStartTime", query.getAppointStartTime());
            example.and().andLessThanOrEqualTo("appointEndTime", query.getAppointEndTime());
        }
        if (Objects.nonNull(query.getCreateTimeStart()) && Objects.nonNull(query.getCreateTimeEnd())) {
            example.and().andBetween("createTime", query.getCreateTimeStart(), query.getCreateTimeEnd());
        }
        if (Integers.notNullAndZero(query.getPayStatus())) {
            example.and().andEqualTo("payStatus", OrderPayStatusEnum.UNPAID.value());
        }
        if (Objects.nonNull(query.getLogisticsStatus())) {
            example.and().andEqualTo("logisticsStatus", query.getLogisticsStatus());
        }
        if (Objects.nonNull(query.getCreateTimeStart()) && Objects.nonNull(query.getCreateTimeEnd())) {
            example.and().andBetween("createTime", query.getCreateTimeStart(), query.getCreateTimeEnd());
        }
        if (Strings.isNotEmpty(query.getPromoteLabel())) {
            example.and().andLike("promoteLabel", Strings.format("%{}%", query.getPromoteLabel()));
        }
        if (Strings.isNotEmpty(query.getPromoteChannel())) {
            example.and().andLike("promoteChannel", Strings.format("%{}%", query.getPromoteChannel()));
        }
        if (Objects.nonNull(query.getCompletePrice())) {
            example.and().andEqualTo("completePrice", query.getCompletePrice());
        }
        if(Objects.nonNull(query.getPartnerId())){
            example.and().andEqualTo("partnerId", query.getPartnerId());
        }
        if (Lists.isNotEmpty(query.getPartnerIdList())) {
            example.and().andIn("partnerId", query.getPartnerIdList());
        }
        if(Integers.notNullAndZero(query.getPartnerType())){
            example.and().andEqualTo("partnerType", query.getPartnerType());
        }
        if (Objects.nonNull(query.getCompleteTimeStart()) && Objects.nonNull(query.getCompleteTimeEnd())) {
            example.and().andBetween("completeTime", query.getCompleteTimeStart(), query.getCompleteTimeEnd());
        }
        if (Lists.isNotEmpty(query.getClerkIdList())) {
            example.and().andIn("clerkId", query.getClerkIdList());
        }
        if (Lists.isNotEmpty(query.getKefuIdList())) {
            example.and().orIn("kefuId", query.getKefuIdList()).orIn("completeKefuId", query.getKefuIdList());
        }
        if (Objects.nonNull(query.getCompleteKefuId())) {
            example.and().andEqualTo("completeKefuId", query.getCompleteKefuId());
        }
		if (Strings.isNotEmpty(query.getProvince())) {
            example.and().andEqualTo("province", query.getProvince());
        }
        if (Strings.isNotEmpty(query.getCity())) {
            example.and().andEqualTo("city", query.getCity());
        }
        if (Strings.isNotEmpty(query.getArea())) {
            example.and().andEqualTo("area", query.getArea());
        }
        if (Strings.isNotEmpty(query.getAreaKeyword())) {
            final String areaKeyword = query.getAreaKeyword().trim();
            example.and().andLike("province", Strings.format("%{}%", areaKeyword))
                    .orLike("city", Strings.format("%{}%", areaKeyword))
                    .orLike("area", Strings.format("%{}%", areaKeyword));
        }
        if (Objects.nonNull(query.getWalletStatus())) {
            example.and().andEqualTo("walletStatus", query.getWalletStatus());
        }
        if (Integers.notNullAndZero(query.getPartnerUserType())) {
            example.and().andGreaterThan("clerkId", 0);
            example.and().andIn("partnerType", PartnerTypeEnum.getPartnerTypeList(query.getPartnerUserType()));
        }
        if (Lists.isNotEmpty(query.getPartnerTypeList())) {
            example.and().andIn("partnerType", query.getPartnerTypeList());
        }
        if (Objects.nonNull(query.getFilterClerk()) && query.getFilterClerk()) {
            example.and().andGreaterThan("clerkId", Numbers.LONG_ZERO);
        }
        if (Integers.notNullAndZero(query.getIsNoCall())) {
            example.and().andIsNull("callTime");
        }
        return example;
    }

    /**
     * 根据订单号查询订单
     */
    public OrderEntity selectByOrderId(Long orderId) {
        Example example = buildExample();
        example.and().andEqualTo("orderId", orderId);
        return selectFirstOneByExample(example);
    }

    /**
     * 根据用户id查询订单数量
     */
//    public OrderStatusNumber selectOrderStatusCountByUserId(Long userId) {
//        return this.mapper.selectOrderStatusCountByUserId(userId);
//    }

    public Integer selectCount(OrderQuery query) {
        return this.selectCountByExample(this.buildExample(query));
    }

    public List<OrderEntity> selectList(OrderQuery query) {
        return this.selectByExample(this.buildExample(query));
    }

//    public Integer getOrderCount(OrderQuery orderQuery) {
//        return this.mapper.getOrderCount(orderQuery);
//    }



    /**
     * 是否有信用回收订单
     */
    public OrderEntity selectCreditOrder(Long userId,Integer cycle) {
        Example example = buildExample();
        example.and().andEqualTo("userId", userId);
        example.and().andNotEqualTo("prepaidStatus", Numbers.INTEGER_ZERO);
        example.and().andGreaterThanOrEqualTo("createTime", Dates.addDays(new Date(), cycle));
        return selectFirstOneByExample(example);
    }

    /**
     * 查询当月支付宝钱包订单
     * @return
     */
    public OrderEntity selectWalletOrder(Long userId,Integer cycle) {
        Example example = buildExample();
        example.and().andEqualTo("userId", userId);
        example.and().andNotEqualTo("walletStatus", Numbers.INTEGER_ZERO);
        example.and().andGreaterThanOrEqualTo("createTime", Dates.addDays(new Date(), cycle));
        return selectFirstOneByExample(example);
    }

    /**
     * 查询合作商当月支付宝钱包订单
     * @return
     */
    public OrderEntity selectPartnerWalletOrder(Long userId,Long partnerId,Integer cycle) {
        Example example = buildExample();
        example.and().andEqualTo("userId", userId);
        example.and().andEqualTo("partnerId", partnerId);
        example.and().andNotEqualTo("walletStatus", Numbers.INTEGER_ZERO);
        example.and().andGreaterThanOrEqualTo("createTime", Dates.addDays(new Date(), cycle));
        return selectFirstOneByExample(example);
    }

    public Integer selectCompleteOrderNumber(OrderQuery query) {
        Example example = this.buildExample(query);
        return selectCountByExample(example);
    }

    /**
     * 查询重复订单
     */
    public OrderEntity selectRepeatOrder(Long orderId, Long userId, Long productId) {
        Example example = buildExample();
        example.and().andNotEqualTo("orderId", orderId);
        example.and().andEqualTo("userId", userId);
        example.and().andEqualTo("productId", productId);
        example.and().andBetween("createTime", Dates.getFirstTime(Dates.getTimeNow()), Dates.getTimeNow());
        return selectFirstOneByExample(example);
    }

    /**
     * 查询重复订单
     */
    public OrderEntity selectClerkRepeatOrder(Long orderId, Long userId) {
        Example example = buildExample();
        example.and().andNotEqualTo("orderId", orderId);
        example.and().andEqualTo("userId", userId);
        example.and().andNotEqualTo("clerkId", Numbers.INTEGER_ZERO);
        example.and().andBetween("createTime", Dates.getFirstTime(Dates.getTimeNow()), Dates.getTimeNow());
        return selectFirstOneByExample(example);
    }

//    public List<ClerkOrderDispatchNumberDTO> selectClerkOrderDispatchNumber() {
//        return this.mapper.selectClerkOrderDispatchNumber();
//    }

    public Integer selectClerkDeliveryOvertimeCount(Long clerkId, Date timeLessThan, List<Long> ignorePartnerIdList, List<Long> ignoreClerkIdList, Date startStopDispatchDate) {
        Example example = this.buildDeliveryOvertimeExample(clerkId, timeLessThan, ignorePartnerIdList, ignoreClerkIdList, startStopDispatchDate);
        return this.selectCountByExample(example);
    }

    public List<OrderEntity> selectClerkDeliveryOvertimeOrderList(Long clerkId, Date timeLessThan, List<Long> ignorePartnerIdList, List<Long> ignoreClerkIdList, Date startStopDispatchDate) {
        // 已完成 待发货 未申请自卖
        Example example = this.buildDeliveryOvertimeExample(clerkId, timeLessThan, ignorePartnerIdList, ignoreClerkIdList, startStopDispatchDate);
        return this.selectByExample(example);
    }



    public Integer selectClerkInStockOvertimeCount(Long clerkId, Date timeLessThan, List<Long> ignorePartnerIdList, List<Long> ignoreClerkIdList, Date startStopDispatchDate) {
        // 已完成，已发货，未入库
        Example example = this.buildInStockOvertimeExample(clerkId, timeLessThan, ignorePartnerIdList, ignoreClerkIdList, startStopDispatchDate);
        return this.selectCountByExample(example);
    }

    public List<OrderEntity> selectClerkInStockOvertimeOrderList(Long clerkId, Date timeLessThan, List<Long> ignorePartnerIdList, List<Long> ignoreClerkIdList, Date startStopDispatchDate) {
        // 已完成，已发货，未入库
        Example example = this.buildInStockOvertimeExample(clerkId, timeLessThan, ignorePartnerIdList, ignoreClerkIdList, startStopDispatchDate);
        return this.selectByExample(example);
    }

    private Example buildInStockOvertimeExample(Long clerkId, Date timeLessThan, List<Long> ignorePartnerIdList, List<Long> ignoreClerkIdList, Date startStopDispatchDate) {
        Example example = this.buildExample();
        example.and().andEqualTo("clerkId", clerkId);
        example.and().andEqualTo("orderStatus", OrderStatusEnum.COMPLETE.value());
        example.and().andLessThan("completeTime", timeLessThan);
        example.and().andEqualTo("logisticsStatus", LogisticsStatusEnum.HAS_DELIVERY.value());
        if (Lists.isNotEmpty(ignorePartnerIdList)) {
            example.and().andNotIn("partnerId", ignorePartnerIdList);
        }
        if (Lists.isNotEmpty(ignoreClerkIdList)) {
            example.and().andNotIn("clerkId", ignoreClerkIdList);
        }
        if (Objects.nonNull(startStopDispatchDate)) {
            example.and().andGreaterThanOrEqualTo("completeTime", startStopDispatchDate);
        }
        return example;
    }

    private Example buildDeliveryOvertimeExample(Long clerkId, Date timeLessThan, List<Long> ignorePartnerIdList, List<Long> ignoreClerkIdList, Date startStopDispatchDate) {
        Example example = this.buildExample();
        example.and().andEqualTo("clerkId", clerkId);
        example.and().andEqualTo("orderStatus", OrderStatusEnum.COMPLETE.value());
        example.and().andLessThan("completeTime", timeLessThan);
        example.and().andEqualTo("logisticsStatus", LogisticsStatusEnum.WAIT_DELIVERY.value());
        if (Lists.isNotEmpty(ignorePartnerIdList)) {
            example.and().andNotIn("partnerId", ignorePartnerIdList);
        }
        if (Lists.isNotEmpty(ignoreClerkIdList)) {
            example.and().andNotIn("clerkId", ignoreClerkIdList);
        }
        if (Objects.nonNull(startStopDispatchDate)) {
            example.and().andGreaterThanOrEqualTo("completeTime", startStopDispatchDate);
        }
        return example;
    }


    public String getOrderCount(OrderQuery orderQuery) {
        return "0";
    }

    /**
     * 根据订单号查询订单
     */
    public OrderEntity selectByOrderNo(String orderNo) {
        if (Strings.isBlank(orderNo)) {
            return null;
        }
        final Example example = this.buildExample();
        example.and().andEqualTo("orderNo", orderNo);
        return this.selectFirstOneByExample(example);
    }

    /**
     * 根据合作商订单号查询订单
     */
    public OrderEntity selectByPartnerOrderNo(String partnerOrderNo) {
        if (Strings.isBlank(partnerOrderNo)) {
            return null;
        }
        final Example example = this.buildExample();
        example.and().andEqualTo("partnerOrderNo", partnerOrderNo);
        return this.selectFirstOneByExample(example);
    }
}
